const express = require('express');
const { Op } = require('sequelize');
const { body, query, param, validationResult } = require('express-validator');
const db = require('../models');
const logger = require('../utils/logger');

// 在文件开头添加模型检查
console.log('Lesson 模型:', db.Lesson);
console.log('Lesson 是否为函数:', typeof db.Lesson);
console.log('db 对象:', Object.keys(db));

const router = express.Router();
const { Lesson, Category, Tag, CodeExample, LessonTag } = db;

// ==================== 公共中间件 ====================

/**
 * 验证请求参数的中间件
 * 检查 express-validator 的验证结果，如果有错误则返回400状态码
 */
const handleValidation = (req, res, next) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({
      error: '请求参数验证失败',
      details: errors.array()
    });
  }
  next();
};

// ==================== 查询功能 ====================

/**
 * 获取课程列表（支持分页、筛选、搜索）
 * GET /lessons
 * 查询参数：
 * - page: 页码（可选，默认1）
 * - limit: 每页数量（可选，默认20，最大100）
 * - categoryId: 分类ID（可选）
 * - difficulty: 难度级别（可选，beginner/intermediate/advanced）
 * - isPublished: 是否发布（可选，布尔值）
 * - isFeatured: 是否推荐（可选，布尔值）
 * - search: 搜索关键词（可选，搜索标题、摘要和内容）
 * - tags: 标签过滤（可选，逗号分隔的标签名或标识）
 */
router.get('/', [
  query('page').optional().isInt({ min: 1 }).withMessage('页码必须是正整数'),
  query('limit').optional().isInt({ min: 1, max: 100 }).withMessage('每页数量必须在1-100之间'),
  query('categoryId').optional().isInt().withMessage('分类ID必须是整数'),
  query('difficulty').optional().isIn(['beginner', 'intermediate', 'advanced']).withMessage('难度级别无效'),
  query('isPublished').optional().isBoolean().withMessage('发布状态必须是布尔值'),
  query('isFeatured').optional().isBoolean().withMessage('推荐状态必须是布尔值'),
  query('search').optional().isLength({ min: 1 }).withMessage('搜索关键词不能为空'),
  query('tags').optional().isString().withMessage('标签必须是字符串'),
  handleValidation
], async (req, res) => {
  try {
    // 测试数据库连接
    await db.sequelize.authenticate();
    console.log('数据库连接正常');
    
    // 使用原生SQL查询检查所有表
    const [tables] = await db.sequelize.query("SHOW TABLES");
    console.log('数据库中的所有表:', tables);
    
    // 添加更详细的调试信息
    console.log('请求查询参数:', req.query);
    
    // 先检查数据库中的所有课程
    const allLessons = await Lesson.findAll({
      attributes: ['id', 'title', 'isPublished', 'categoryId'],
      limit: 5 // 只查看前5条
    });
    console.log('数据库中前5条课程数据:', JSON.stringify(allLessons, null, 2));
    
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) || 20;
    const offset = (page - 1) * limit;
    
    console.log('分页参数 - page:', page, 'limit:', limit, 'offset:', offset);

    // 构建查询条件
    const where = {};
    
    if (req.query.categoryId) {
      where.categoryId = parseInt(req.query.categoryId);
    }
    
    if (req.query.difficulty) {
      where.difficulty = req.query.difficulty;
    }
    
    if (req.query.isPublished !== undefined) {
      where.isPublished = req.query.isPublished === 'true';
    }
    
    if (req.query.isFeatured !== undefined) {
      where.isFeatured = req.query.isFeatured === 'true';
    }
    
    if (req.query.search) {
      where[Op.or] = [
        { title: { [Op.like]: `%${req.query.search}%` } },
        { excerpt: { [Op.like]: `%${req.query.search}%` } },
        { content: { [Op.like]: `%${req.query.search}%` } }
      ];
    }

    // 构建include
    const include = [
      {
        model: Category,
        as: 'category',
        attributes: ['id', 'name', 'slug', 'icon', 'color']
      },
      {
        model: Tag,
        as: 'tags',
        attributes: ['id', 'name', 'slug', 'color'],
        through: { attributes: [] }
      }
    ];

    // 如果有标签过滤
    if (req.query.tags) {
      const tagList = req.query.tags.split(',').map(t => t.trim());
      include[1].where = {
        [Op.or]: [
          { name: { [Op.in]: tagList } },
          { slug: { [Op.in]: tagList } }
        ]
      };
    }

    // 执行查询前先检查总数
    const totalCount = await Lesson.count({ where });
    console.log('符合条件的总记录数:', totalCount);

    const { count, rows } = await Lesson.findAndCountAll({
      where,
      include,
      order: [
        ['isFeatured', 'DESC'],
        ['sortOrder', 'ASC'],
        ['created_at', 'DESC'],
      ],
      limit,
      offset,
      distinct: true
    });

    console.log('findAndCountAll 结果 - 总数:', count, '当前页数据条数:', rows.length);
    console.log('返回的数据ID列表:', rows.map(row => row.id));

    const result = {
      data: rows,
      pagination: {
        page,
        limit,
        total: count,
        pages: Math.ceil(count / limit)
      }
    };
    
    console.log('即将返回的响应结构:', {
      dataCount: result.data.length,
      pagination: result.pagination
    });

    res.json(result);

    logger.info(`获取课程列表完成 - 总数: ${count}, 当前页: ${rows.length}`);

  } catch (error) {
    logger.error('获取课程列表失败:', error);
    console.error('详细错误:', error);
    res.status(500).json({ error: '获取课程列表失败' });
  }
});

/**
 * 获取推荐课程
 * GET /lessons/featured
 * 返回推荐课程列表，支持限制返回数量
 */
router.get('/featured', [
  query('limit').optional().isInt({ min: 1, max: 20 }).withMessage('数量必须在1-20之间'),
  handleValidation
], async (req, res) => {
  try {
    const limit = parseInt(req.query.limit) || 10;
    console.log('获取推荐课程 - 限制数量:', limit);

    const lessons = await Lesson.findAll({
      where: { 
        isPublished: true,
        isFeatured: true 
      },
      include: [
        {
          model: Category,
          as: 'category',
          attributes: ['id', 'name', 'slug', 'icon', 'color']
        },
        {
          model: Tag,
          as: 'tags',
          attributes: ['id', 'name', 'slug', 'color'],
          through: { attributes: [] }
        }
      ],
      order: [['sortOrder', 'ASC'], ['created_at', 'DESC']],
      limit
    });

    console.log(`获取到 ${lessons.length} 个推荐课程`);
    logger.info(`获取推荐课程成功 - 数量: ${lessons.length}`);

    res.json({ data: lessons });

  } catch (error) {
    logger.error('获取推荐课程失败:', error);
    console.error('详细错误:', error);
    res.status(500).json({ error: '获取推荐课程失败' });
  }
});

/**
 * 获取最新课程
 * GET /lessons/recent
 * 返回最新发布的课程列表，支持限制返回数量
 */
router.get('/recent', [
  query('limit').optional().isInt({ min: 1, max: 20 }).withMessage('数量必须在1-20之间'),
  handleValidation
], async (req, res) => {
  try {
    const limit = parseInt(req.query.limit) || 10;
    console.log('获取最新课程 - 限制数量:', limit);

    const lessons = await Lesson.findAll({
      where: { isPublished: true },
      include: [
        {
          model: Category,
          as: 'category',
          attributes: ['id', 'name', 'slug', 'icon', 'color']
        },
        {
          model: Tag,
          as: 'tags',
          attributes: ['id', 'name', 'slug', 'color'],
          through: { attributes: [] }
        }
      ],
      order: [['created_at', 'DESC']],
      limit
    });

    console.log(`获取到 ${lessons.length} 个最新课程`);
    logger.info(`获取最新课程成功 - 数量: ${lessons.length}`);

    res.json({ data: lessons });

  } catch (error) {
    logger.error('获取最新课程失败:', error);
    console.error('详细错误:', error);
    res.status(500).json({ error: '获取最新课程失败' });
  }
});

/**
 * 根据ID获取课程详情
 * GET /lessons/:id
 * 返回完整的课程信息，包括分类、标签和代码示例
 */
router.get('/:id', [
  param('id').isInt().withMessage('课程ID必须是整数'),
  handleValidation
], async (req, res) => {
  try {
    console.log('获取课程详情 - ID:', req.params.id);
    
    const lesson = await Lesson.findByPk(req.params.id, {
      include: [
        {
          model: Category,
          as: 'category',
          attributes: ['id', 'name', 'slug', 'icon', 'color']
        },
        {
          model: Tag,
          as: 'tags',
          attributes: ['id', 'name', 'slug', 'color'],
          through: { attributes: [] }
        },
        {
          model: CodeExample,
          as: 'codeExamples',
          order: [['sortOrder', 'ASC'], ['createdAt', 'ASC']]
        }
      ]
    });

    if (!lesson) {
      logger.info(`获取课程详情失败: 课程不存在 (ID: ${req.params.id})`);
      return res.status(404).json({ error: '课程不存在' });
    }

    // 增加浏览量
    await lesson.increment('viewCount');
    logger.info(`课程浏览量增加: ${lesson.title} (ID: ${lesson.id}), 当前浏览量: ${lesson.viewCount + 1}`);

    res.json({ data: lesson });
    logger.info(`获取课程详情成功: ${lesson.title} (ID: ${lesson.id})`);

  } catch (error) {
    logger.error('获取课程详情失败:', error);
    console.error('详细错误:', error);
    res.status(500).json({ error: '获取课程详情失败' });
  }
});

// 根据slug获取课程详情
router.get('/slug/:slug', [
  param('slug').isLength({ min: 1 }).withMessage('课程标识不能为空'),
  handleValidation
], async (req, res) => {
  try {
    const lesson = await Lesson.findOne({
      where: { slug: req.params.slug },
      include: [
        {
          model: Category,
          as: 'category',
          attributes: ['id', 'name', 'slug', 'icon', 'color']
        },
        {
          model: Tag,
          as: 'tags',
          attributes: ['id', 'name', 'slug', 'color'],
          through: { attributes: [] }
        },
        {
          model: CodeExample,
          as: 'codeExamples',
          order: [['sortOrder', 'ASC'], ['createdAt', 'ASC']]
        }
      ]
    });

    if (!lesson) {
      return res.status(404).json({ error: '课程不存在' });
    }

    // 增加浏览量
    await lesson.increment('viewCount');

    res.json({ data: lesson });

  } catch (error) {
    logger.error('获取课程详情失败:', error);
    res.status(500).json({ error: '获取课程详情失败' });
  }
});

/**
 * 创建新课程
 * POST /lessons
 * 支持创建课程并关联标签
 */
router.post('/', [
  body('categoryId').isInt().withMessage('分类ID必须是整数'),
  body('title').notEmpty().withMessage('课程标题不能为空'),
  body('slug').notEmpty().withMessage('课程标识不能为空'),
  body('content').notEmpty().withMessage('课程内容不能为空'),
  body('excerpt').optional().isLength({ max: 1000 }).withMessage('摘要不能超过1000字符'),
  body('coverImage').optional().custom((value) => {
    // 允许相对路径或完整URL
    if (value.startsWith('/') || value.startsWith('http://') || value.startsWith('https://')) {
      return true;
    }
    throw new Error('封面图片路径格式无效');
  }),
  body('difficulty').optional().isIn(['beginner', 'intermediate', 'advanced']).withMessage('难度级别无效'),
  body('duration').optional().isInt({ min: 1 }).withMessage('学习时长必须是正整数'),
  body('sortOrder').optional().isInt().withMessage('排序权重必须是整数'),
  body('isPublished').optional().isBoolean().withMessage('发布状态必须是布尔值'),
  body('isFeatured').optional().isBoolean().withMessage('推荐状态必须是布尔值'),
  body('author').optional().isLength({ max: 100 }).withMessage('作者名称不能超过100字符'),
  body('metaKeywords').optional().isLength({ max: 255 }).withMessage('SEO关键词不能超过255字符'),
  body('metaDescription').optional().isLength({ max: 255 }).withMessage('SEO描述不能超过255字符'),
  body('tags').optional().isArray().withMessage('标签必须是数组'),
  handleValidation
], async (req, res) => {
  const transaction = await db.sequelize.transaction();
  
  try {
    console.log('创建课程 - 请求数据:', req.body);
    
    const { tags, ...lessonData } = req.body;

    // 创建课程
    const lesson = await Lesson.create(lessonData, { transaction });
    logger.info(`课程创建成功: ${lesson.title} (ID: ${lesson.id})`);

    // 添加标签关联
    if (tags && tags.length > 0) {
      const tagIds = [];
      
      for (const tagName of tags) {
        const [tag] = await Tag.findOrCreate({
          where: { name: tagName },
          defaults: {
            slug: tagName.toLowerCase().replace(/[^a-z0-9]/g, '-'),
            name: tagName
          },
          transaction
        });
        tagIds.push(tag.id);
        logger.info(`标签关联成功: ${tag.name} (ID: ${tag.id})`);
      }
      
      await lesson.setTags(tagIds, { transaction });
      logger.info(`课程标签设置完成: ${lesson.title} (ID: ${lesson.id}), 标签数: ${tagIds.length}`);
    }

    await transaction.commit();
    
    res.status(201).json({
      message: '课程创建成功',
      data: lesson
    });

  } catch (error) {
    await transaction.rollback();
    logger.error('创建课程失败:', error);
    console.error('详细错误:', error);
    
    if (error.name === 'SequelizeUniqueConstraintError') {
      return res.status(409).json({ error: '课程标识已存在' });
    }
    
    res.status(500).json({ error: '创建课程失败' });
  }
});

/**
 * 更新课程信息
 * PUT /lessons/:id
 * 支持部分更新，只更新提供的字段
 */
router.put('/:id', [
  param('id').isInt().withMessage('课程ID必须是整数'),
  body('categoryId').optional().isInt().withMessage('分类ID必须是整数'),
  body('title').optional().notEmpty().withMessage('课程标题不能为空'),
  body('slug').optional().notEmpty().withMessage('课程标识不能为空'),
  body('content').optional().notEmpty().withMessage('课程内容不能为空'),
  body('excerpt').optional().isLength({ max: 1000 }).withMessage('摘要不能超过1000字符'),
  body('coverImage').optional().custom((value) => {
    // 允许相对路径或完整URL
    if (value.startsWith('/') || value.startsWith('http://') || value.startsWith('https://')) {
      return true;
    }
    throw new Error('封面图片路径格式无效');
  }),
  body('difficulty').optional().isIn(['beginner', 'intermediate', 'advanced']).withMessage('难度级别无效'),
  body('duration').optional().isInt({ min: 1 }).withMessage('学习时长必须是正整数'),
  body('sortOrder').optional().isInt().withMessage('排序权重必须是整数'),
  body('isPublished').optional().isBoolean().withMessage('发布状态必须是布尔值'),
  body('isFeatured').optional().isBoolean().withMessage('推荐状态必须是布尔值'),
  body('author').optional().isLength({ max: 100 }).withMessage('作者名称不能超过100字符'),
  body('metaKeywords').optional().isLength({ max: 255 }).withMessage('SEO关键词不能超过255字符'),
  body('metaDescription').optional().isLength({ max: 255 }).withMessage('SEO描述不能超过255字符'),
  body('tags').optional().isArray().withMessage('标签必须是数组'),
  handleValidation
], async (req, res) => {
  const transaction = await db.sequelize.transaction();
  
  try {
    console.log('更新课程 - ID:', req.params.id, '请求数据:', req.body);
    
    const lesson = await Lesson.findByPk(req.params.id);
    
    if (!lesson) {
      await transaction.rollback();
      logger.info(`更新课程失败: 课程不存在 (ID: ${req.params.id})`);
      return res.status(404).json({ error: '课程不存在' });
    }

    const { tags, ...lessonData } = req.body;

    // 更新课程信息
    await lesson.update(lessonData, { transaction });
    logger.info(`课程信息更新成功: ${lesson.title} (ID: ${lesson.id})`);

    // 更新标签关联
    if (tags !== undefined) {
      if (tags.length === 0) {
        await lesson.setTags([], { transaction });
        logger.info(`课程标签已清空: ${lesson.title} (ID: ${lesson.id})`);
      } else {
        const tagIds = [];
        
        for (const tagName of tags) {
          const [tag] = await Tag.findOrCreate({
            where: { name: tagName },
            defaults: {
              slug: tagName.toLowerCase().replace(/[^a-z0-9]/g, '-'),
              name: tagName
            },
            transaction
          });
          tagIds.push(tag.id);
          logger.info(`标签关联成功: ${tag.name} (ID: ${tag.id})`);
        }
        
        await lesson.setTags(tagIds, { transaction });
        logger.info(`课程标签更新完成: ${lesson.title} (ID: ${lesson.id}), 标签数: ${tagIds.length}`);
      }
    }

    await transaction.commit();
    
    res.json({
      message: '课程更新成功',
      data: lesson
    });

  } catch (error) {
    await transaction.rollback();
    logger.error('更新课程失败:', error);
    console.error('详细错误:', error);
    
    if (error.name === 'SequelizeUniqueConstraintError') {
      return res.status(409).json({ error: '课程标识已存在' });
    }
    
    res.status(500).json({ error: '更新课程失败' });
  }
});

/**
 * 删除课程
 * DELETE /lessons/:id
 * 删除前会检查是否有关联的代码示例
 */
router.delete('/:id', [
  param('id').isInt().withMessage('课程ID必须是整数'),
  handleValidation
], async (req, res) => {
  const transaction = await db.sequelize.transaction();
  
  try {
    console.log('删除课程 - ID:', req.params.id);
    
    const lesson = await Lesson.findByPk(req.params.id);
    
    if (!lesson) {
      await transaction.rollback();
      logger.info(`删除课程失败: 课程不存在 (ID: ${req.params.id})`);
      return res.status(404).json({ error: '课程不存在' });
    }

    // 检查是否有关联的代码示例
    const codeExampleCount = await CodeExample.count({
      where: { lessonId: req.params.id }
    });
    
    if (codeExampleCount > 0) {
      await transaction.rollback();
      logger.info(`删除课程失败: 存在 ${codeExampleCount} 个关联的代码示例 (ID: ${req.params.id})`);
      return res.status(400).json({ 
        error: `存在 ${codeExampleCount} 个关联的代码示例，无法删除` 
      });
    }

    // 删除标签关联
    await lesson.setTags([], { transaction });
    logger.info(`课程标签关联已删除: ${lesson.title} (ID: ${lesson.id})`);

    // 删除课程
    await lesson.destroy({ transaction });
    logger.info(`课程删除成功: ${lesson.title} (ID: ${lesson.id})`);

    await transaction.commit();
    
    res.json({ message: '课程删除成功' });

  } catch (error) {
    await transaction.rollback();
    logger.error('删除课程失败:', error);
    console.error('详细错误:', error);
    res.status(500).json({ error: '删除课程失败' });
  }
});

/**
 * 点赞课程
 * POST /lessons/:id/like
 * 增加课程的点赞数
 */
router.post('/:id/like', [
  param('id').isInt().withMessage('课程ID必须是整数'),
  handleValidation
], async (req, res) => {
  try {
    console.log('点赞课程 - ID:', req.params.id);
    
    const lesson = await Lesson.findByPk(req.params.id);
    
    if (!lesson) {
      logger.info(`点赞课程失败: 课程不存在 (ID: ${req.params.id})`);
      return res.status(404).json({ error: '课程不存在' });
    }

    // 增加点赞数
    await lesson.increment('likeCount');
    const updatedLesson = await Lesson.findByPk(req.params.id);
    
    logger.info(`课程点赞成功: ${lesson.title} (ID: ${lesson.id}), 当前点赞数: ${updatedLesson.likeCount}`);
    
    res.json({ 
      message: '点赞成功',
      likeCount: updatedLesson.likeCount
    });

  } catch (error) {
    logger.error('点赞课程失败:', error);
    console.error('详细错误:', error);
    res.status(500).json({ error: '点赞失败' });
  }
});

module.exports = router; 